package com.quan.hr.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.quan.commons.core.MyBaseServiceImpl;
import com.quan.commons.interceptor.LoginUserInterceptor;
import com.quan.commons.utils.*;
import com.quan.hr.entity.HrDept;
import com.quan.hr.entity.HrPost;
import com.quan.hr.service.HrDeptService;
import com.quan.hr.service.HrPostService;
import com.quan.system.commons.vo.SysUserVo;
import com.quan.system.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import com.quan.hr.commons.vo.HrEmployeeVo;
import com.quan.hr.entity.HrEmployee;
import com.quan.hr.mapper.HrEmployeeMapper;
import com.quan.hr.service.HrEmployeeService;


@Slf4j
@Service
@DS("master")
public class HrEmployeeServiceImpl extends MyBaseServiceImpl<HrEmployeeMapper, HrEmployee> implements HrEmployeeService {

    @Autowired
    private HrEmployeeMapper mapper;

    @Autowired
    private HrDeptService deptService;

    @Autowired
    private HrPostService postService;

    @Autowired
    private SysUserService userService;

    @Override
    public boolean save(HrEmployeeVo vo) {
        // 身份证获取出生日期
        final String birthByIdCard = IdCardUtils.getBirthByIdCard(vo.getIdCardNo());
        // 性别
        final String gender = IdCardUtils.getGenderByIdCard(vo.getIdCardNo());
        vo.setSex(gender.equals("男")?"1":"2");
        // 出生日期
        final String birthDate = DateUtils.format(DateUtils.parse(birthByIdCard, "yyyyMMdd"), "yyyy-MM-dd");
        vo.setBirthday(DateUtils.UDateToLocalDate(DateUtils.parseDate(birthDate)));

        if(null == vo.getEmail() || vo.getEmail().trim().equals("")){
            vo.setEmail(Pinyin4jHelper.getPinYin(vo.getName()) + "@whizen.com");
        }


        final boolean flag = super.save(vo);

        if(flag) {
            // 创建用户
            SysUserVo u = new SysUserVo();
            u.setEmpId(vo.getId());
            u.setEmpName(vo.getName());
            u.setUsername(vo.getWorkNo());
            u.setRealname(vo.getName());
            u.setMobile(vo.getTelephone());
            if(null == vo.getEmail() || vo.getEmail().trim().equals("")){
                u.setEmail(Pinyin4jHelper.getPinYin(vo.getName()) + "@whizen.com");
            } else {
                u.setEmail(vo.getEmail());
            }
            u.setSex(vo.getSex());
            u.setBirthday(vo.getBirthday());
            this.userService.saveUser(u);
        }

        return flag;
    }

    @Override
    public boolean updateById(HrEmployeeVo vo) {
        if(vo.getStatus().equals("0")) {
            vo.setQuitDate(null);
        }

        final SysUserVo user = LoginUserInterceptor.loginUser.get();
        vo.setUname(null != user.getEmpName() ? user.getEmpName() : user.getUsername());

        return super.updateById(vo);
    }

    /**
     * 加载员工信息
     * @param id
     * @return
     */
    @Override
    public HrEmployeeVo getInfo(Long id) {
        final HrEmployee employee = super.getById(id);

        HrEmployeeVo bean = new HrEmployeeVo();
        BeanUtils.copyProperties(employee, bean);

        if(null != bean.getDeptId()) {
            // 部门反推获取节点的父路径
            bean.setCascaderDeptPathVals(this.deptService.findPath(bean.getDeptId()));
        }
        if(null != bean.getPostId()) {
            // 岗位反推获取节点的父路径
            bean.setCascaderPostPathVals(this.postService.findPath(bean.getPostId()));
        }

        // 年龄
        bean.setAge(IdCardUtils.getAgeByIdCard(bean.getIdCardNo()));

        // 计算社龄：获取（入职日期-离职日期）两个日期相差天数 / 365
        Date end = bean.getStatus().equals("1") || bean.getStatus().equals("2") ? DateUtils.LocalDateToUdate(bean.getQuitDate()) : new Date();
        double distanceOfTwoDate = DateUtils.getDistanceOfTwoDate(DateUtils.LocalDateToUdate(bean.getJoinDate()), end);
        String workAge = MathUtil.format((distanceOfTwoDate / 365), "#.#");
        bean.setWorkAge(workAge);

        // 部门
        if(null != bean.getDeptId()){
            final HrDept dept = this.deptService.getById(bean.getDeptId());
            if(null != dept) {
                bean.setDeptName(dept.getName());
            }
        }

        // 岗位
        if(null != bean.getPostId()){
            final HrPost post = this.postService.getById(bean.getPostId());
            if(null != post) {
                bean.setPostName(post.getName());
            }
        }

        return bean;
    }

    @Override
    public List<HrEmployeeVo> queryList(PageUtils pageUtils, HrEmployeeVo vo) {
        QueryWrapper<HrEmployee> queryWrapper = new QueryWrapper<HrEmployee>(vo);

        List<HrEmployee> list = super.list(pageUtils, queryWrapper);
        List<HrEmployeeVo> collect = list.stream().map(item -> {
                HrEmployeeVo bean = new HrEmployeeVo();
            BeanUtils.copyProperties(item, bean);
            return bean;
        }).collect(Collectors.toList());

        return collect;
    }

    @Override
    public PageUtils queryPage(PageUtils pageUtils, HrEmployeeVo vo) {
        QueryWrapper<HrEmployee> queryWrapper = new QueryWrapper<HrEmployee>(vo);

        if (StringUtils.isNotBlank(vo.getKeyword())) {
            queryWrapper.and(w -> {
                w.like("work_no", vo.getKeyword()).or().like("name", vo.getKeyword());
            });
        }
        // 入职日期范围
        if (StringUtils.isNotEmpty(vo.getJoinDateRange())) {
            final String[] split = vo.getJoinDateRange().split(",");
            String startDate = split[0];
            String endDate = split[1];
            queryWrapper.apply("date_format(join_date, '%Y-%m-%d') >= {0} and date_format(join_date, '%Y-%m-%d') <= {1}", startDate, endDate);
        }


        super.handleSort(queryWrapper, pageUtils);
        final IPage<HrEmployee> page = super.selectPage(pageUtils, queryWrapper);

        PageUtils ps = new PageUtils(page);

        final List<HrEmployee> records = page.getRecords();

        final List<HrEmployee> collect = records.stream().map((item) -> {
            HrEmployeeVo bean = new HrEmployeeVo();
            BeanUtils.copyProperties(item, bean);

            // 年龄
            bean.setAge(IdCardUtils.getAgeByIdCard(bean.getIdCardNo()));

            // 计算在司年限：获取（入职日期-离职日期）两个日期相差天数 / 365
            Date end = bean.getStatus().equals("1") || bean.getStatus().equals("2") ? DateUtils.LocalDateToUdate(bean.getQuitDate()) : new Date();
            double distanceOfTwoDate = DateUtils.getDistanceOfTwoDate(DateUtils.LocalDateToUdate(bean.getJoinDate()), end);
            String workAge = MathUtil.format((distanceOfTwoDate / 365), "#.#");
            bean.setWorkAge(workAge);

            // 部门
            if(null != item.getDeptId()){
                final HrDept dept = this.deptService.getById(item.getDeptId());
                if(null != dept) {
                    bean.setDeptName(dept.getName());
                }
            }

            // 岗位
            if(null != item.getPostId()){
                final HrPost post = this.postService.getById(item.getPostId());
                if(null != post) {
                    bean.setPostName(post.getName());
                }
            }

            return bean;
        }).collect(Collectors.toList());

        ps.setRecords(collect);
        return ps;
    }

    @Override
    public boolean batchSettingStatus(HrEmployeeVo vo) {

        final LambdaUpdateWrapper<HrEmployee> updateWrapper = new UpdateWrapper<HrEmployee>().lambda();
        updateWrapper.set(HrEmployee::getStatus, vo.getStatus());
        if(null != vo.getQuitDate()) {
            updateWrapper.set(HrEmployee::getQuitDate, vo.getQuitDate());
        } else {
            updateWrapper.set(HrEmployee::getQuitDate, null);
        }

        updateWrapper.in(HrEmployee::getId, vo.getIds());

        return super.update(updateWrapper);
    }


    @Override
    public boolean batchSettingDept(HrEmployeeVo vo) {

        final LambdaUpdateWrapper<HrEmployee> updateWrapper = new UpdateWrapper<HrEmployee>().lambda();
        updateWrapper.set(HrEmployee::getDeptId, vo.getDeptId());
        updateWrapper.in(HrEmployee::getId, vo.getIds());

        return super.update(updateWrapper);
    }


    @Override
    public boolean batchSettingPost(HrEmployeeVo vo) {

        final LambdaUpdateWrapper<HrEmployee> updateWrapper = new UpdateWrapper<HrEmployee>().lambda();
        updateWrapper.set(HrEmployee::getPostId, vo.getPostId());
        updateWrapper.in(HrEmployee::getId, vo.getIds());

        return super.update(updateWrapper);
    }
}